package cc.telecomdigital.tdstock.Framework.UniqueItem;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import cc.telecomdigital.tdstock.ITDLApplication;
import cc.telecomdigital.tdstock.SystemInfo;
import cc.telecomdigital.tdstock.Framework.UniqueItem.NetworkChangeListener.CONNECT_TYPE;
import cc.telecomdigital.tdstock.Tools.EncryptionAlg;

public class DeviceInfo
{
	public static final int		orientation_SensorType	= Sensor.TYPE_ACCELEROMETER;
	private static final boolean  debugMode                = false;
	private static final String   LOG_TAG                  = "DeviceInfo";

	static public final String	gprsReason			= "gprsDetached";

	/** Check if orientation sensor is available on the device **/
	public static boolean IsOrientationSensorAvailable(Context iCallerContext)
	{
		SensorManager sensorManager;

		sensorManager = (SensorManager) iCallerContext
				.getSystemService(Activity.SENSOR_SERVICE);
		if (sensorManager == null)
			return false;
		
		if (sensorManager.getDefaultSensor(DeviceInfo.orientation_SensorType) == null)
			return false;

		return true;
	}

	/** Get the Device Model **/
	public static String GetDeviceModel()
	{
		return android.os.Build.MODEL;
	}

	/** Get the Device Type
	    2 for android **/
	public static String GetDeviceTypeID()
	{
		return "2";
	}

	/** Check if we are on an emulator, might be true, if the device is being rooted **/
	public static boolean IsOnEmualtor()
	{
		if (android.provider.Settings.Secure.ANDROID_ID == null)
			return true;

		return false;
	}

	/** If it has a phone feature, we consider as a phone. The priority is
	    phone, pad, nothing **/
	public static String GetDeviceType(Context iContext)
	{
		return "iphone";

//		int phoneType;
//		String infoString;
//
//		phoneType = ((TelephonyManager) iContext
//				.getSystemService(Context.TELEPHONY_SERVICE))
//				.getPhoneType();
//		// If there is phone exist
//		if (phoneType != TelephonyManager.PHONE_TYPE_NONE)
//			return "android_phone";
//
//		WifiManager wifiManager;
//		wifiManager = (WifiManager) iContext
//				.getSystemService(Context.WIFI_SERVICE);
//		if (wifiManager != null)
//		{
//			infoString = wifiManager.getConnectionInfo().getMacAddress();
//			if (infoString != null)
//				return "android_pad";
//		}
//
//		return "";
	}
	
	private static String keySet = "@@deviceinfotrace@@";

	public static String GetDeviceExtraInfo(Context iContext)
	{
		String extraInfo;
		extraInfo = "XMF_" + android.os.Build.MANUFACTURER
				+ "XBR_" + android.os.Build.BRAND
				+ "XML_" + android.os.Build.MODEL
				+ "XPD_" + android.os.Build.PRODUCT
				+ "XID_" + android.os.Build.ID
				+ "XDV_" + android.os.Build.DEVICE 
				+ "XRL_" + android.os.Build.VERSION.RELEASE
				+ "XSK_" + android.os.Build.VERSION.SDK
				+ "XUT_" + String.valueOf(android.os.SystemClock.elapsedRealtime()).toString()
				+ "XMC_" + GetWifiMacAddress(iContext)
				+ "XMI_"  + GetIMEI(iContext);
        
		if (debugMode)
			TDStockLog.i("Exam", "***** ExtraInfo = " + extraInfo);
        
		try
		{
			extraInfo = EncryptionAlg.encrypt(keySet, extraInfo);
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
			TDStockLog.e(LOG_TAG, "getDeviceExtraInfo=>Exception: " + ex.toString());	            
		}

		return extraInfo;
	}	
	
	
	static private String versionName = null;
	public static String GetVersionName(Context iContext)
	{
		if (versionName != null)
			return versionName;
		
		PackageInfo packageInfo;
		try
		{
			packageInfo = iContext.getPackageManager().getPackageInfo(iContext.getPackageName(), 0);
			versionName = packageInfo.versionName;
		}
		catch (NameNotFoundException e)
		{
		    e.printStackTrace();
		    versionName = null;
		    //return a temporary version
		    return "NA";
		} 		
		
		return versionName;
	}

	/** Get the OS Version, Android Kernel,
	    4.2 is the iPhone iOS **/
	static public String GetOSVersion()
	{
		return android.os.Build.VERSION.RELEASE;
	}

	/** Device Version is the hardware specification made by the manufacturer **/
	// 1.06 Device Ver, like the Hardware manufacturing version
	static public String GetDeviceVersion()
	{
		return android.os.Build.DEVICE;
	}

	/** Device ID, it is our self-manager ID that comes with the combination
	    of WIFI-macAddress and Modem IMEI, After a trial get, the device id will be set
	    and get only once **/	
	static private String deviceID = null;
	public static String GetDeviceID(Context iContext)
	{
		deviceID = SystemInfo.GetDeviceIdAuthWifiMac(iContext)[1];
		
		if("".equals(deviceID))
		{
			deviceID = SystemInfo.getDeviceId(iContext, "delay");
		}
//		if (deviceID == null)			
//		{
//			//Try to get one
//			String deviceInfo1, deviceInfo2;
//			
//			deviceInfo1 = GetWifiMacAddress(iContext);
//			deviceInfo2 = GetIMEI(iContext);
//			deviceID 	= deviceInfo1 + deviceInfo2;
//			deviceID    = UUID.nameUUIDFromBytes(deviceID.getBytes()).toString();			
//			deviceID 	= deviceID.replace("-", "00");
//		}			

		if (debugMode)
			TDStockLog.i(LOG_TAG, "GetDeviceID: " + deviceID);
		
		return deviceID;
	}

	private static String wifiStoreMac = null;
	/** Get the WiFi Mac Address, if wifi is off, an enforce will be happened **/
	private static String GetWifiMacAddress(Context iContext)
	{		
		if (wifiStoreMac != null)
			return wifiStoreMac;
	
		WifiManager wifiManager;
		WifiInfo    wifiInfo;
		String      infoString;		
		String      nullReplacement;
		boolean prevState;		
		
		nullReplacement = "00:00:00:00:00:00";
		//Guess there is no wifi hardware in the device
		wifiManager 	 = (WifiManager) iContext.getSystemService(Context.WIFI_SERVICE);
		if (wifiManager == null)
		{
			wifiStoreMac = nullReplacement;		
			return nullReplacement;
		}
				
		prevState = false;		
		infoString = nullReplacement;
		
		long timesamp = System.currentTimeMillis();
		try
		{
			/* Try to turn on WiFi if it is no on */
			prevState  = wifiManager.isWifiEnabled();			
			if (prevState == false)
			{
				if (debugMode)
					TDStockLog.i(LOG_TAG, "Enforce to turn on Wifi to read MAC");
				wifiManager.setWifiEnabled(true);
				//According to Haibo design
				do
				{
					wifiInfo = wifiManager.getConnectionInfo();
					if(wifiInfo != null)
					{
						infoString = wifiInfo.getMacAddress();
						if ((infoString != null) && (infoString.equals(nullReplacement) == false))
							break;
					}
					
					infoString = nullReplacement;
					if((System.currentTimeMillis() - timesamp) >= 10000)
						break;

					Thread.sleep(300);						
					
				} while (infoString.equals(nullReplacement) || (infoString == null));							
			}
			else
				infoString = wifiManager.getConnectionInfo().getMacAddress();
		}			
		catch(Exception ex)
		{
			TDStockLog.e(LOG_TAG,"GetWifiMacAddress: " + ex.toString());	
		}
		finally
		{
			//Change back its state
			wifiManager.setWifiEnabled(prevState);			
		}
		
		if (infoString == null)
			infoString = nullReplacement;
		
		if (nullReplacement.equals(infoString) == false)
			wifiStoreMac = infoString;
		
		//Default Empty Address
		return infoString;
	}

	/** Get the Modem IMEI, unique ID if it has one **/
	private static String GetIMEI(Context context)
	{
		String           infoString;
		String 		  nullReplaceMent;
		TelephonyManager teleManager;
		
		nullReplaceMent = "000000000000000";
		teleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		if (teleManager == null)
			return nullReplaceMent;

		infoString = teleManager.getDeviceId();
		if(infoString == null || infoString.length() == 0)
			infoString = nullReplaceMent;
		
		return infoString;
	}

	/** Get the Current Time Stamp in format
		2011-03-15 12:05:24 Asia/Hong_Kong (HKT) offset 28800");
		Local time zone **/
	static public String GetCurrentTimeStamp()
	{
		// Format
		// "2011-03-15 12:05:24 Asia/Hong_Kong (HKT) offset 28800");
		// Local time zone
		TimeZone zone;
		String tmpString;
		SimpleDateFormat dateTimeFormat;

		dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		zone = TimeZone.getDefault();

		tmpString = dateTimeFormat.format(Calendar.getInstance().getTime());
		tmpString += " " + zone.getID() + " offset ";
		tmpString += String.valueOf(zone.getRawOffset() / 1000);

		return tmpString;
	}

	/** Get the Current Date Stamp in format
	    "2011-03-15" **/
	static public String GetCurrentDateStamp()
	{
		// Format
		// "2011-03-15"
		SimpleDateFormat dateTimeFormat;

		dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateTimeFormat.format(Calendar.getInstance().getTime());
	}
	
	/** Self made location string **/
	static public String GetCurrentLocation()
	{
		return "hk";
	}

	/** Use the current OS Language, we should always goes with Chinese **/
	static public String GetLanguageString()
	{
//		String langPref;
//
//		langPref = java.util.Locale.getDefault().toString();
//		// Check for most Chinese
//		if (langPref.startsWith("zh", 0) == true)
//			return "lang_cht";
//
//		//for testing
//		if (testing)
//			return "lang_cht";
//
//		return langPref;
		return "lang_cht";
	}

	/** Check with the Connection Manager whether we have network **/
	static public boolean IsNetworkAvailable(Context iContext)
	{
		if (GetCurrentConnectionType(iContext) != CONNECT_TYPE.NONE)
			return true;

		return false;
	}

	/** Check with the connection manager on current connection type, GRPS,
	    WIFI, MOBILE, NONE **/
	static public CONNECT_TYPE GetCurrentConnectionType(Context iContext)
	{
		if (iContext == null)
			return CONNECT_TYPE.NONE;

		ConnectivityManager connectivity = (ConnectivityManager) iContext
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity == null)
			return CONNECT_TYPE.NONE;

		CONNECT_TYPE curType;
		NetworkInfo[] netInfos;

		curType = CONNECT_TYPE.NONE;
		netInfos = connectivity.getAllNetworkInfo();
		if (netInfos == null)
			return curType;

		for (NetworkInfo netInfo : netInfos)
		{
			if (netInfo.getType() == ConnectivityManager.TYPE_WIFI)
			{
				//Highest proiority, return immedidatelty
				if (netInfo.isConnected())
					return CONNECT_TYPE.WIFI;
			}

			if (netInfo.getType() == ConnectivityManager.TYPE_MOBILE)
			{
				//Second Priority
				if (netInfo.isConnected())
					curType = CONNECT_TYPE.MOBILE_DATA;
				else if (curType == CONNECT_TYPE.NONE)
				{
					if ((netInfo.getReason() != null) && netInfo.getReason().equals(gprsReason))
						curType = CONNECT_TYPE.GRPS_DATA;
				}
			}
		}

		return curType;
	}
}
